﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Linq;
using iTextSharp.text;
using iTextSharp.text.pdf;
using NHibernate;
using NHibernate.Cfg;
using NHibernate.Criterion;
using NHibernate.Dialect;
using NHibernate.SqlCommand;
using Studentium.Entities;
using Studentium.UIElements;
using Studentium.Util;
using TopCoder.Util.Calendar.Entry;
using TopCoder.Util.Calendar.Entry.Impl;
using TopCoder.WinForms.Controls.CalendarView;
using Image = System.Drawing.Image;

namespace Studentium
{
    public partial class MainForm : Form
    {
        private ISessionFactory sessionFactory;                
        private SplashScreen splash;
        private Thread splashThread;
        public static string password;

        //public static List<string> PaidClasses = new List<string>();
        public static MainForm Instance;

        public StudentsControl StudentsControl
        {
            get { return studentsControl; }
        }


        public void ShowSplash()
        {
            splash = new SplashScreen();
            splash.StartPosition = FormStartPosition.CenterScreen;
            splash.ShowDialog();
        }

        public MainForm()
        {
            CultureInfo culture = (CultureInfo)CultureInfo.CurrentCulture.Clone();
            culture.DateTimeFormat.ShortTimePattern = "HH:mm";
            culture.DateTimeFormat.LongTimePattern = "HH:mm";
            culture.DateTimeFormat.ShortDatePattern = "dd_MM_yyyy";
            Thread.CurrentThread.CurrentCulture = culture;

            Instance = this;

            splashThread = new Thread(new ThreadStart(ShowSplash));
            splashThread.Start();

            InitializeComponent();            
            
            calendarViewControl.CurrentViewType = "Week";
            curriculumDatePicker.Value = DateTime.Now;
#if !DEBUG
            try
            {
#endif
                Configuration config = new Configuration();
                config.Configure();

                CloseSplashScreen();

                LoginDialog login = new LoginDialog();
                login.StartPosition = FormStartPosition.CenterScreen;
                DialogResult result = login.ShowDialog(this);
                if (result != System.Windows.Forms.DialogResult.Yes)
                    Close();

                string connectionStr = config.GetProperty("connection.connection_string");                
                Regex r = new Regex("Password=");
                Match match = r.Match(connectionStr);
                match.Groups.GetEnumerator().MoveNext();                                
                config.SetProperty("connection.connection_string", r.Split(connectionStr)[0] + "Password=" + password);

                sessionFactory = config.BuildSessionFactory();                
            
                //string[] ddl = config.GenerateSchemaCreationScript(new MySQLDialect());
                //Log.log("DDL for DB: \n" + String.Join("\n", ddl));

                //session = GetSession();
                ReloadCalendar();
                ReloadBooks();
                
                splashThread.Abort();

#if !DEBUG
            }
            catch(Exception e)
            {
                Log.log("Exception during configuring nhibernate and creating session factory", e);
                MessageBox.Show("Error during connection to data base!", "Error", MessageBoxButtons.OK,
                                MessageBoxIcon.Error);
                CloseSplashScreen();
                throw;
            }
#endif


            // attach child controls to this form in order to get NHibernate session
            //potentionalControl.MainController = this;
            studentsControl.MainController = this;
            calendarViewControl.MainController = this;

        }

        private void ReloadBooks()
        {
            using (ISession session = GetSession())
            {
                booksGrid.Rows.Clear();
                IList students = session.CreateSQLQuery("select Student.BusinessId,Student.FirstName,Student.LastName,"
                + "Payment.MoneyPaid, Payment.BookType, Payment.BookLevel, Payment.Comment from Student left join Payment on Student.id = Payment.studentId "
                + " where Payment.IsBookPayment = 1").List();

                booksGrid.ColumnCount = 7;

                booksGrid.Columns[0].Name = "Id";
                booksGrid.Columns[1].Name = "First Name";
                booksGrid.Columns[2].Name = "Last Name";
                booksGrid.Columns[3].Name = "Money Paid";
                booksGrid.Columns[4].Name = "Book Type";
                booksGrid.Columns[5].Name = "Book Level";
                booksGrid.Columns[6].Name = "Comment";
                booksGrid.Columns[6].Width = 200;

                for (int rowIndex = 0; rowIndex < students.Count; ++rowIndex)
                {
                    var row = new DataGridViewRow();

                    for (int columnIndex = 0; columnIndex < 7; ++columnIndex)
                    {
                        object value = ((object[]) (students[rowIndex]))[columnIndex];
                        if (columnIndex == 4 && value != null)
                            value = (BookType) value;
                        if (columnIndex == 5 && value != null)
                            value = (StudentLevel)value;
                        row.Cells.Add(new DataGridViewTextBoxCell()
                        {
                            Value = value
                        });
                    }

                    booksGrid.Rows.Add(row);
                }                
            }
        }

        delegate void CloseSplashScreenCallback();

        private void CloseSplashScreen()
        {
            if (splash.InvokeRequired)
            {
                var callBack = new CloseSplashScreenCallback(CloseSplashScreen);
                splash.Invoke(callBack);
            }
            else
            {
                splash.Close();
            }
        }

        public ISession GetSession()
        {
#if !DEBUG
            try
            {
#endif
                return sessionFactory.OpenSession();
#if !DEBUG
            }
            catch(Exception e)
            {
                Log.log("Exception during opening nhibernate session", e);
                MessageBox.Show("Error during connection to data base!", "Error", MessageBoxButtons.OK,
                                MessageBoxIcon.Error);
                return null;
            }
#endif
        }

        private void addScheduleEntryBtn_Click(object sender, EventArgs e)
        {
            DateTime date = calendarViewControl.GetView(calendarViewControl.CurrentViewType).DateOfInterest;
            EditScheduleEntry form = new EditScheduleEntry(new CalendarEntry { Date = date }, this, true);
            form.Show(this);
        }

        internal void ReloadCalendar()
        {
            using (ISession session = GetSession())
            {
                calendarViewControl.Data = session.CreateCriteria(typeof (CalendarEntry)).List<CalendarEntry>();
            }
        }

        public IList<CalendarEntry> GetCalendarEntries(DateTime date)
        {
            return Helper.SelectEntriesByDateTimeRange(calendarViewControl.Data, 
                                                    new DateTime(date.Year,date.Month, date.Day),
                                                    new DateTime(date.Year, date.Month, date.Day).AddDays(1).AddMinutes(-1) );
        }

        public int GetAttendancesNumber(CalendarEntry entry)
        {
            using (ISession session = GetSession())
            {
                return session.CreateCriteria(typeof (ClassAttendance))
                        .Add(Restrictions.Eq("CalendarEntry", entry))
                        .Add(Restrictions.Not(Restrictions.Eq("Status", AttendenceStatus.WishList)))
                        .List().Count;
            }
        }

        private void OnRefreshBtn_Click(object sender, EventArgs e)
        {
            ReloadBooks();
        }

        private void OnFinishingBtn_Click(object sender, EventArgs e)
        {
            using (ISession session = GetSession())
            {
                ReportGenerator.GenerateFinishingStudents(session);
            }
        }

        private void curriculumBtn_Click(object sender, EventArgs e)
        {
            using (ISession session = GetSession())
            {
                ReportGenerator.GenerateCurriculum(session, curriculumDatePicker.Value);
            }
        }

        private void tabControl1_Click(object sender, EventArgs e)
        {
            if (((TabControl)sender).SelectedTab == books)
                ReloadBooks();
        }
    }
}
